#include "draw_api.h"
#include "oledfont2.h"
#include "oled.h"
#include <math.h>

#define uint unsigned int
#define uchar unsigned char

dpi_dw OledDraw;
dpi_sw OledShow;
dpi_cav OledCanvas;
dpi_funcstr OledPaint;


unsigned char BMP[1024]={
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	};

void CanvasClear(void){
	unsigned int i=0;
	for(i=0;i<1024;i++)
	{
		BMP[i]=0x00;
	}
}

uchar func_y(float k,unsigned char x1,uchar y1,uchar x)
{
	float a=k*(x-x1)+y1;
	float b=k*(x-x1)+y1+0.5;
	if((uchar)b>(uchar)a)
		return b;
	else
		return a;
}

uchar func_x(float k,uchar x1,uchar y1,uchar y)
{
	float a=(y-y1)/k+x1;
	float b=(y-y1)/k+x1+0.5;
	if((uchar)b>(uchar)a)
		return b;
	else
	{
		return a;
	}

}

void Draw_Point(uchar x,uchar y){
	
	uchar page,i;
	page=y/8;
	i=y%8;
	BMP[page*8*16+x]|=(0x01<<i);
}

void Draw_Line(uchar x1,uchar y1,uchar x2,uchar y2){
	double k;
	uchar n;
	if(x1!=x2){
		k=(float)(y2-y1)/(float)(x2-x1);
		if(k>1)
		{
			for(n=y1;n<=y2;n++)
			{
				Draw_Point(func_x(k,x2,y2,n),n);
			}
		}
		if(k<-1)
		{
			for(n=y1;n>=y2;n--)
			{
				Draw_Point(func_x(k,x1,y1,n),n);
			}
		}
		if(k<=1&&k>=-1)
		{
			for(n=x1;n<=x2;n++){
				Draw_Point(n,func_y(k,x1,y1,n));
			}
		}
	}
	else
	{
		for(n=y1;n<y2;n++)
			Draw_Point(x1,n);
	}
}


void Draw_Rect(uchar x1,uchar y1,uchar x2,uchar y2,uchar Full){
	if(Full==0){
		Draw_Line(x1,y1,x2,y1);
		Draw_Line(x1,y2,x2,y2);
		Draw_Line(x1,y1,x1,y2);
		Draw_Line(x2,y1,x2,y2);
	}
	if(Full==1){
		uchar i=0;
		for(i=0;i<(y2-y1+1);i++){
			Draw_Line(x1,y1+i,x2,y1+i);
		}
	}
}

void Draw_Tri(uchar x1,uchar y1,uchar x2,uchar y2,uchar x3,uchar y3){
	Draw_Line(x1,y1,x2,y2);
	Draw_Line(x1,y1,x3,y3);
	Draw_Line(x2,y2,x3,y3);
}

void Draw_Circle(uchar x,uchar y,uchar r){
	float dx,dy;
	uchar i;
	for(i=0;i<90;i+=1){
		dx=(float)r*sin(i);
		dy=(float)r*cos(i);
		Draw_Point(x+(uchar)dx,y+(uchar)dy);
		Draw_Point(x-(uchar)dx,y-(uchar)dy);
		Draw_Point(x+(uchar)dx,y-(uchar)dy);
		Draw_Point(x-(uchar)dx,y+(uchar)dy);
	}
}

void Draw_Picture(uchar x,uchar y,uchar picture_Length,uchar picture_width,const unsigned char* Img)
{
	uchar dy,y_page,i,j,y_page_need,pic_y_delta;
	int picAryLen=0,picAryCut;
	y_page = y/8;
	y_page_need = picture_width/8;
	pic_y_delta = y%8;
	picAryLen = (y_page_need+1)*picture_Length;
	picAryCut = 0;
	for(j=y_page;j<y_page+y_page_need+1;j++)
		for(i=x;i<x+picture_Length;i++)
		{
			BMP[i+j*128]|=(Img[picAryCut]>>pic_y_delta);
			BMP[i+(j+1)*128]|=(Img[picAryCut++]<<(8-pic_y_delta));
		}
}


void OLED_ShowCharRAM(uchar x,uchar y,uchar CHAR,uchar fontsize){
	uchar i,j;
	j=CHAR-32;
	if(fontsize==16)
	{
		for(i=0;i<8;i++)
		{
			BMP[y*16*8+x+i]=CHAR16x8[j*16+i];
		}
		y+=1;
		for(i=0;i<8;i++)
		{
			BMP[y*16*8+x+i]=CHAR16x8[j*16+i+8];
		}
	}
	else
	{
		for(i=0;i<6;i++)
		{
			BMP[y*16*8+x+i]=CHAR8x6[j][i];
		}
	}
}

//����������д���ַ���
void OLED_ShowStrRAM(uchar x,uchar y,uchar*chr,uchar fontsize){
	uchar j=0,spacing;
	
	if(fontsize==16) spacing=8;
	else spacing=6; //�����ּ��
	
	while(chr[j]!='\0')
	{
		OLED_ShowCharRAM(x,y,chr[j],fontsize);
		x+=spacing; //�����ּ��Ϊspacing
		
		if(x>120)//������Ļ�Զ�����
		{
			x=0;
			y+=2;
		}
		j++;
	}
}

long int oled_pow(unsigned char m,unsigned char n)
{
	long int result=1;	 
	while(n--)result*=m;    
	return result;
}				  
//��ʾ2������
//x,y :�������	 
//len :���ֵ�λ��
//size:�����С
//mode:ģʽ	0,���ģʽ;1,����ģʽ
//num:��ֵ(0~4294967295);	 		  
void OLED_ShowNumRAM(unsigned char x,unsigned char y,long int num,unsigned char len,unsigned char size)
{         	
	unsigned char t,temp;
	unsigned char enshow=0;						   
	for(t=0;t<len;t++)
	{
		temp=(num/oled_pow(10,len-t-1))%10;
		if(enshow==0&&t<(len-1))
		{
			if(temp==0)
			{
				OLED_ShowCharRAM(x+(size/2)*t,y,' ',size);
				continue;
			}else enshow=1; 
		}
		OLED_ShowCharRAM(x+(size/2)*t,y,temp+'0',size);
	}
}

void DisPlay(void){
	OLED_DrawBMP(0,0,128,8,BMP);
}

void IPText_WriteChar(unsigned char *text,unsigned char x,unsigned char y,unsigned char CHAR,unsigned char fontsize){
	unsigned char i,j;
	j=CHAR-32;
	if(fontsize==16)
	{
		for(i=0;i<8;i++)
		{
			text[x+i]=CHAR16x8[j*16+i];
		}
		y+=1;
		for(i=0;i<8;i++)
		{
			text[y*120+x+i]=CHAR16x8[j*16+i+8];
		}
	}
	else
	{
		for(i=0;i<6;i++)
		{
			text[y*120+x+i]=CHAR8x6[j][i];
		}
	}
}

void IPText_WriteString(unsigned char *text,unsigned char*chr,unsigned char fontsize){
	unsigned char j=0,spacing,x=0,y=0;
	
	if(fontsize==16) spacing=8;
	else spacing=6;
	
	while(chr[j]!='\0')
	{
		IPText_WriteChar(text,x,y,chr[j],fontsize);
		x+=spacing;
		j++;
        if(x>104)
        {
            IPText_WriteChar(text,x-8,y,' ',fontsize);
        }
		if(x>=120)
		{
			break;
		}
	}
}

int sque(int input)
{
	if(input>=120)
	{
		return input-120;
	}
	else
		return input;
}

void Draw_PicPart(unsigned char begin_x,unsigned char *newpic,unsigned char *pic)
{
	for(int i=0;i<32;i++)
	{
		newpic[i] = pic[sque(begin_x+i)];
		newpic[i+32] = pic[sque(begin_x+i)+120];
	}
}

void Oled_DrawApi_Init()
{
	OLED_Init();
	
	OledDraw.Point = Draw_Point;
	OledDraw.Line = Draw_Line;
	OledDraw.Circle = Draw_Circle;
	OledDraw.Tri = Draw_Tri;
	OledDraw.Rect = Draw_Rect;
	OledDraw.Picture = Draw_Picture;

	OledShow.Char = OLED_ShowCharRAM;
	OledShow.Str = OLED_ShowStrRAM;
	OledShow.Number = OLED_ShowNumRAM;

	OledCanvas.Display = DisPlay;
	OledCanvas.Clear = CanvasClear;

	OledPaint.Draw = OledDraw;
	OledPaint.Show = OledShow;
	OledPaint.Canvas = OledCanvas;
	
	
	
}




